#include<event2/event.h>
#include<signal.h>
#include<iostream>
#include <string.h>
#include<errno.h>
using namespace std;
//数据来时边缘触发只进入一次,需
void ETclient_cb(evutil_socket_t sock,short whice,void *arg)
{
    //判断超时
    cout<<"."<<flush<<endl;
    if(whice&EV_TIMEOUT)
    {
        cout<<"timeout"<<endl;
        event *ev=(event *)arg;
        event_free(ev);
        evutil_closesocket(sock);
        return;
    }
   
    //char buf[1024]={0};

    //int len=recv(sock,buf,1023,0);
    // if(len>0)
    // {
    //     cout<<buf<<endl;
    //     send(sock,"ok",2,0);
    // }
    // else
//     {
//          //需要清理event
//         cout<<"event_free"<<endl;
//         event *ev=(event *)arg;
//         event_free(ev);
//         evutil_closesocket(sock);
//     }

}
//水平触发，只要有数据会一直进入
//正常断开连接会进入，超时也会进入
void client_cb(evutil_socket_t sock,short whice,void *arg)
{
    //判断超时
    
    if(whice&EV_TIMEOUT)
    {
        cout<<"timeout"<<endl;
        event *ev=(event *)arg;
        event_free(ev);
        evutil_closesocket(sock);
        return;
    }
   
    char buf[1024]={0};

    int len=recv(sock,buf,1023,0);
    if(len>0)
    {
        cout<<buf<<endl;
        send(sock,"ok",2,0);
    }
    else
    {
         //需要清理event
        cout<<"event_free"<<endl;
        event *ev=(event *)arg;
        event_free(ev);
        evutil_closesocket(sock);
    }

}
void listen_cb(evutil_socket_t sock,short whice,void *arg)
{
    cout<<"listen_cb"<<endl;
    //读取连接信息
    sockaddr_in sin;
    socklen_t size=sizeof(sin);
    evutil_socket_t client = accept(sock,(sockaddr*)&sin,&size);
    char ip[16]={0};
    evutil_inet_ntop(AF_INET,&sin.sin_addr,ip,sizeof(ip)-1);
    cout<<"client ip is"<<ip<<endl;
    //客户端数据读取事件
    //event *ev=event_new((event_base*)arg,client,EV_READ|EV_PERSIST,client_cb,event_self_cbarg());
    //边缘触发
    event *ev=event_new((event_base*)arg,client,EV_READ|EV_PERSIST|EV_ET,ETclient_cb,event_self_cbarg());
    timeval t1={10,0};
    event_add(ev,&t1);
}

int main(int argc,char **argv)
{
    // event_config *ec= event_config_new();
    // event_base *eb=event_base_new_with_config(ec);

    // event_base_free(eb);
    // event_config_free(ec);
    if(signal(SIGPIPE,SIG_IGN)==SIG_ERR)
    {
        return 1;
    }
    //event 服务器
    event_base *eb=event_base_new();
    //创建socket
    evutil_socket_t sock =socket(AF_INET,SOCK_STREAM,0);
    if(sock<=0)
    {
        cerr<<"socket failed"<<strerror(errno)<<endl;
        return -1;
    }
    //设置地址复用和非阻塞
    evutil_make_socket_nonblocking(sock);
    evutil_make_listen_socket_reuseable(sock);
    sockaddr_in sin;
    memset(&sin,0,sizeof(sockaddr_in));
    sin.sin_family=AF_INET;
    sin.sin_port=htons(6666);
    //绑定端口和地址
    int re=::bind(sock,(sockaddr *)&sin,sizeof(sin));
    if(re!=0)
    {
        cerr<<"bind error"<<strerror(errno)<<endl;
        return -1;
    }
    //开始监听
    listen(sock,10);
    //监听连接事件 默认水平触发
    event *ev=event_new(eb,sock,EV_READ|EV_PERSIST,listen_cb,eb);
    event_add(ev,0);
    //进入事件主循环
    event_base_dispatch(eb);
    evutil_closesocket(sock);
    event_base_free(eb);
    
    return 0;
}